package com.ljl.mvvmdemo.ui.activity

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import com.ljl.mvvmdemo.BR
import com.ljl.mvvmdemo.ui.dialog.LoadingDialog
import com.ljl.mvvmdemo.util.ActivityUtils
import com.ljl.mvvmdemo.util.BUNDLE
import com.ljl.mvvmdemo.util.CLASS
import com.ljl.mvvmdemo.util.REQUEST_CODE
import com.ljl.mvvmdemo.viewmodel.BaseViewModel
import java.lang.reflect.ParameterizedType

/**
 * Activity基类
 * created by luojialun on 2024/4/10
 */
abstract class BaseActivity<DB : ViewDataBinding, VM : BaseViewModel> : AppCompatActivity() {

    lateinit var binding: DB
    lateinit var viewModel: VM

    var loadingDialog: LoadingDialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityUtils.instance.addActivity(this)
        binding = DataBindingUtil.setContentView(this, getLayoutId())
        binding.lifecycleOwner = this
        viewModel = ViewModelProvider(this).get(getViewModelClass())
        binding.setVariable(BR.viewModel, viewModel)
        lifecycle.addObserver(viewModel)

        initParam()
        initView()

        initObservable()
    }

    open fun getViewModelClass(): Class<VM> {
        return (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
    }

    abstract fun getLayoutId(): Int

    open fun initParam() {}

    open fun initView() {}

    private fun initObservable() {
        viewModel.showLoadingEvent.observe(this, { tip ->
            showLoadingDialog(tip)
        })
        viewModel.dismissLoadingEvent.observe(this, {
            dismissLoadingDialog()
        })
        viewModel.startActivityEvent.observe(this, { map ->
            val clazz = map[CLASS] as Class<*>
            val intent = Intent(this, clazz)
            map[BUNDLE]?.let {
                val bundle = it as Bundle
                intent.putExtras(bundle)
            }
            val requestCode = map[REQUEST_CODE] as Int
            startActivityForResult(intent, requestCode)
        })
    }

    private fun showLoadingDialog(tip: String = "") {
        dismissLoadingDialog()
        loadingDialog = LoadingDialog(tip)
        loadingDialog?.run {
            if (!isAdded && !isFinishing) {
                show(supportFragmentManager, "LoadingDialog")
            }
        }
    }

    private fun dismissLoadingDialog() {
        loadingDialog?.dismissAllowingStateLoss()
        loadingDialog = null
    }

    override fun onDestroy() {
        super.onDestroy()
        ActivityUtils.instance.removeActivity(this)
        binding.unbind()
        lifecycle.removeObserver(viewModel)
    }

}